package edu.njucm.herbiv.utils

import io.github.oshai.kotlinlogging.KotlinLogging
import java.nio.file.Path
import kotlin.io.path.Path

private val logger = KotlinLogging.logger {}

/**
 * @Author ZhouHang
 * @Date 24/7/19 周五
 */
object ProcessUtils {
    private val herbivHOME = Path(System.getenv("HERBIV_HOME"))
    private val scriptPath = herbivHOME.resolve("herbiv-cli.py")
    val herbivCommand = listOf(pyExe(), scriptPath.toAbsolutePath().toString())

    /**
     * 兼容不同操作系统
     * @return Windows 则返回 python；Linux 返回 python3
     * */
    private fun pyExe(): String {
        return if (System.getProperty("os.name").startsWith("Windows")) "python"; else "python3"
    }

    /**
     * 阻塞开启进程执行命令，忽略任何输出和错误处理
     * @param cmd 待执行的命令
     * @param log 是否日志记录执行的命令
     * @param file 将进程的输出放到文件中
     * */
    fun runCommand(cmd: List<String>, log: Boolean = true, file: Path? = null): Process? {
        if (log) logger.info { "[exe] ${cmd.joinToString(separator = " ")}" }
        if (file == null) ProcessBuilder(cmd).start().waitFor()
        else {
            val process = ProcessBuilder(cmd).redirectOutput(file.toFile())
            return process.start()
        }
        return null;
    }

    /**
     * 针对命令输出的每一行都进行回调函数的处理和判断
     * @param cmd 待执行的命令
     * @param log 是否日志记录执行的命令
     * @param callback 对进程输出的每一行进行回调处理，参数为每行的文本
     * */
    fun runCommand(cmd: List<String>, log: Boolean = true, callback: (String) -> Unit): Process? {
        if (log) logger.info { "[exe] ${cmd.joinToString(separator = " ")}" }
        val processBuilder = ProcessBuilder(cmd).redirectErrorStream(true)
        val process = processBuilder.start()
        process.inputStream.bufferedReader().useLines { lines ->
            lines.forEach { line -> callback(line) }
        }
        return process
    }
}
